home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / xvisrc.zip / TOS.C < prev    next >
C/C++ Source or Header  |  1992-07-28  |  8KB  |  438 lines

  1. /* Copyright (c) 1990,1991,1992 Chris and John Downey */
  2. #ifndef lint
  3. static char *sccsid = "@(#)tos.c    2.1 (Chris & John Downey) 7/29/92";
  4. #endif
  5.  
  6. /***
  7.  
  8. * program name:
  9.     xvi
  10. * function:
  11.     Portable version of UNIX "vi" editor, with extensions.
  12. * module name:
  13.     tos.c
  14. * module function:
  15.     System interface module for the Atari ST.
  16. * history:
  17.     STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  18.     Originally by Tim Thompson (twitch!tjt)
  19.     Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  20.     Heavily modified by Chris & John Downey
  21.  
  22.     Atari port modified by Steve Found for LATTICE C V5.0
  23.  
  24. ***/
  25.  
  26. #include "xvi.h"
  27.  
  28. #include <osbind.h>
  29.  
  30. /*
  31.  * The following buffer is used to work around a bug in TOS. It appears that
  32.  * unread console input can cause a crash, but only if console output is
  33.  * going on. The solution is to always grab any unread input before putting
  34.  * out a character. The following buffer holds any characters read in this
  35.  * fashion. The problem can be easily produced because we can't yet keep
  36.  * up with the normal auto-repeat rate in insert mode.
  37.  */
  38. #define IBUFSZ    128
  39.  
  40. static    long    inbuf[IBUFSZ];        /* buffer for unread input */
  41. static    long    *inptr = inbuf;        /* where to put next character */
  42.  
  43. /*
  44.  * These are globals which are set by the OS-specific module,
  45.  * and used for various purposes throughout the rest of xvi.
  46.  */
  47. int    Rows;                /* Number of Rows and Columns */
  48. int    Columns;            /* in the current window. */
  49.  
  50. static    char    tmpbuff[L_tmpnam];
  51. static    char    *logscreen;
  52.  
  53. /*
  54.  * inchar() - get a character from the keyboard
  55.  *
  56.  * Certain special keys are mapped to values above 0x80. These
  57.  * mappings are defined in keymap.h. If the key has a non-zero
  58.  * ascii value, it is simply returned. Otherwise it may be a
  59.  * special key we want to map.
  60.  *
  61.  * The ST has a bug involving keyboard input that seems to occur
  62.  * when typing quickly, especially typing capital letters. Sometimes
  63.  * a value of 0x02540000 is read. This doesn't correspond to anything
  64.  * on the keyboard, according to my documentation. My solution is to
  65.  * loop when any unknown key is seen. Normally, the bell is rung to
  66.  * indicate the error. If the "bug" value is seen, we ignore it completely.
  67.  *
  68.  * "timeout" parameter not handled at the moment.
  69.  */
  70. int
  71. inchar(timeout)
  72. long    timeout;
  73. {
  74.     int        k, s;
  75.  
  76.     for (;;) {
  77.     long c;
  78.  
  79.     /*
  80.      * Get the next input character, either from the input
  81.      * buffer or directly from TOS.
  82.      */
  83.     if (inptr != inbuf) {    /* input in the buffer, use it */
  84.         long    *p;
  85.  
  86.         c = inbuf[0];
  87.         /*
  88.          * Shift everything else in the buffer down. This
  89.          * would be cleaner if we used a circular buffer,
  90.          * but it really isn't worth it.
  91.          */
  92.         inptr--;
  93.         for (p = inbuf; p < inptr ;p++)
  94.         *p = *(p+1);
  95.     } else {
  96.         c = Crawcin();
  97.     }
  98.  
  99.     k = (c & 0xFF);
  100.     s = (c >> 16) & 0xFF;
  101.     if (k != 0)
  102.         break;
  103.  
  104.     switch (s) {
  105.  
  106.     case 0x62: k = K_HELP; break;
  107.     case 0x61: k = K_UNDO; break;
  108.     case 0x52: k = K_INSERT; break;
  109.     case 0x47: k = K_HOME; break;
  110.     case 0x48: k = K_UARROW; break;
  111.     case 0x50: k = K_DARROW; break;
  112.     case 0x4b: k = K_LARROW; break;
  113.     case 0x4d: k = K_RARROW; break;
  114.     case 0x29: k = K_CGRAVE; break; /* control grave accent */
  115.  
  116.     /*
  117.      * Occurs due to a bug in TOS.
  118.      */
  119.     case 0x54:
  120.         break;
  121.  
  122.     /*
  123.      * Add the function keys here later if we put in support
  124.      * for macros.
  125.      */
  126.  
  127.     default:
  128.         k = 0;
  129.         alert();
  130.         break;
  131.     }
  132.  
  133.     if (k != 0) {
  134.         break;
  135.     }
  136.     }
  137.     return(k);
  138. }
  139.  
  140. /*
  141.  * get_inchars - snarf away any pending console input
  142.  *
  143.  * If the buffer overflows, we discard what's left and ring the bell.
  144.  */
  145. static void
  146. get_inchars()
  147. {
  148.     while (Cconis()) {
  149.     if (inptr >= &inbuf[IBUFSZ]) {    /* no room in buffer? */
  150.         Crawcin();        /* discard the input */
  151.         alert();            /* and sound the alarm */
  152.     } else {
  153.         *inptr++ = Crawcin();
  154.     }
  155.     }
  156. }
  157.  
  158. void
  159. outchar(c)
  160. char    c;
  161. {
  162.     get_inchars();
  163.     Cconout((short)c);
  164. }
  165.  
  166. void
  167. outstr(s)
  168. register char    *s;
  169. {
  170.     get_inchars();
  171.     Cconws(s);
  172. }
  173.  
  174. #define BGND    0
  175. #define TEXT    1
  176.  
  177. /*
  178.  * vbeep() - visual bell
  179.  */
  180. static void
  181. vbeep()
  182. {
  183.     int        text, bgnd;        /* text and background colors */
  184.     long    l;
  185.  
  186.     text = Setcolor(TEXT, -1);
  187.     bgnd = Setcolor(BGND, -1);
  188.  
  189.     Setcolor(TEXT, (short) bgnd);        /* swap colors */
  190.     Setcolor(BGND, (short) text);
  191.  
  192.     for (l=0; l < 5000 ;l++)    /* short pause */
  193.     ;
  194.  
  195.     Setcolor(TEXT, (short) text);        /* restore colors */
  196.     Setcolor(BGND, (short) bgnd);
  197. }
  198.  
  199. void
  200. alert()
  201. {
  202.     if (Pb(P_vbell))
  203.     vbeep();
  204.     else
  205.     outchar('\007');
  206. }
  207.  
  208. bool_t
  209. can_write(file)
  210. char    *file;
  211. {
  212.     if (access(file, 0) == -1 || access(file, 2) == 0) {
  213.     return(TRUE);
  214.     } else {
  215.     return(FALSE);
  216.     }
  217. }
  218.  
  219. /*
  220.  * remove(file) - remove a file
  221.  * I don't know whether success is detectable here - cmd.
  222.  */
  223. #ifndef LATTICE
  224. bool_t
  225. remove(file)
  226. char    *file;
  227. {
  228.     Fdelete(file);
  229.     return(TRUE);
  230. }
  231. #endif
  232.  
  233. void
  234. sys_init()
  235. {
  236.     logscreen = (char *) Logbase();
  237.     if (Getrez() == 0)
  238.     Columns = 40;        /* low resolution */
  239.     else
  240.     Columns = 80;        /* medium or high */
  241.  
  242.     Rows = 25;
  243.  
  244.     Cursconf(1, NULL);
  245. }
  246.  
  247. void
  248. sys_startv()
  249. {
  250. }
  251.  
  252. void
  253. sys_endv()
  254. {
  255. }
  256.  
  257. void
  258. sys_exit(r)
  259. int    r;
  260. {
  261.     tty_goto(25, 0);
  262.     outchar('\n');
  263.     exit(r);
  264. }
  265.  
  266. void
  267. tty_goto(r, c)
  268. int    r, c;
  269. {
  270.     outstr("\033Y");
  271.     outchar(r + ' ');
  272.     outchar(c + ' ');
  273. }
  274.  
  275. /*
  276.  * System calls or library routines missing in TOS.
  277.  */
  278.  
  279. void
  280. sleep(n)
  281. unsigned    n;
  282. {
  283.     int        k;
  284.  
  285.     k = Tgettime();
  286.     while (Tgettime() <= k + n)
  287.     ;
  288. }
  289.  
  290. void
  291. delay()
  292. {
  293.     long    n;
  294.  
  295.     for (n = 0; n < 8000; n++)
  296.     ;
  297. }
  298.  
  299. #ifndef LATTICE
  300. int
  301. system(cmd)
  302. char    *cmd;
  303. {
  304.     char    arg[1];
  305.  
  306.     arg[0] = '\0';        /* no arguments passed to the shell */
  307.  
  308.     if (Pexec(0, cmd, arg, 0L) < 0) {
  309.     return(-1);
  310.     } else {
  311.     return(0);
  312.     }
  313. }
  314. #endif
  315.  
  316. #ifdef    MEGAMAX
  317. char *
  318. strchr(s, c)
  319. char    *s;
  320. int    c;
  321. {
  322.     do {
  323.     if (*s == c)
  324.         return(s);
  325.     } while (*s++);
  326.  
  327.     return(NULL);
  328. }
  329. #endif /* MEGAMAX */
  330.  
  331. /*
  332.  * getenv() - get a string from the environment
  333.  *
  334.  * Both Alcyon and Megamax are missing getenv(). This routine works for
  335.  * both compilers and with the Beckemeyer and Gulam shells. With gulam,
  336.  * the env_style variable should be set to either "mw" or "gu".
  337.  */
  338. #ifndef LATTICE
  339. char *
  340. getenv(name)
  341. char    *name;
  342. {
  343.     extern long    _base;
  344.     char    *envp, *p;
  345.  
  346.     envp = *((char **) (_base + 0x2c));
  347.  
  348.     for ( ; *envp; envp += strlen(envp) + 1) {
  349.     if (strncmp(envp, name, strlen(name)) == 0) {
  350.         p = envp + strlen(name);
  351.         if (*p++ == '=')
  352.         return(p);
  353.     }
  354.     }
  355.     return(NULL);
  356. }
  357. #endif
  358.  
  359. /*
  360.  * Set the specified colour. Just does standout/standend mode for now.
  361.  * Optimisation here to avoid setting standend when we aren't in
  362.  * standout; assumes calling routines are well-behaved (i.e. only do
  363.  * screen movement in P_colour) or some terminals will write garbage
  364.  * all over the screen.
  365.  */
  366. void
  367. set_colour(c)
  368. int    c;
  369. {
  370.     static int    oldc = -1;
  371.  
  372.     if (c == oldc)
  373.     return;
  374.  
  375.     if (c != 0)
  376.     outstr("\033p");
  377.     else
  378.     outstr("\033q");
  379.  
  380.     oldc = c;
  381. }
  382.  
  383. /*
  384.  * tempfname - Create a temporary file name.
  385.  */
  386. char *
  387. tempfname(srcname)
  388. char *srcname;
  389. {
  390.     return(tmpnam(tmpbuff));
  391. }
  392.  
  393. #ifndef ABS
  394. #    define ABS(n) ((n) < 0 ? -(n) : (n))
  395. #endif
  396.  
  397. /*
  398.  * Scroll the ST Monochrome screen.
  399.  */
  400. void
  401. st_scroll(start, end, nlines)
  402. unsigned start, end;
  403. int nlines;
  404. {
  405.     char *s, *e, *d;
  406.     char *s2;
  407.     size_t bytes, clr_bytes;
  408.  
  409.     if (ABS(nlines) > (end + 1 - start) || nlines == 0)
  410.     return;
  411.  
  412.     invis_cursor();
  413.  
  414.     if (nlines > 0) {
  415.     d = logscreen + (start * 1280);
  416.     s = d + (nlines * 1280);
  417.     s2 = d + bytes;
  418.     } else /* (nlines < 0) */ {
  419.     nlines = -nlines;
  420.     s2 = s = logscreen + (start * 1280);
  421.     d = s + (nlines * 1280);
  422.     }
  423.  
  424.     /*
  425.      * Move the appropriate lines up or down.
  426.      */
  427.     bytes = (end + 1 - start - nlines) * 1280;
  428.     memmove(d, s, bytes);
  429.  
  430.     /*
  431.      * Clear the ones left behind.
  432.      */
  433.     clr_bytes = ((end + 1 - start) * 1280) - bytes;
  434.     (void) memset(s2, 0, clr_bytes);
  435.  
  436.     vis_cursor();
  437. }
  438.